package com.example.chenjun.myapplication.fragment;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.chenjun.myapplication.R;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class BannerFragment extends Fragment {

    private ViewPager mVpBanner;
    private ViewpagerAdapter mAdapter;
    private PollingHandler mHandler;
    private boolean isPolling;
    private List<View> mCurrentViewList;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.app_fragment_banner, container, false);
        mVpBanner = view.findViewById(R.id.vp_banner);
        mAdapter = new ViewpagerAdapter();
        mVpBanner.setAdapter(mAdapter);
        mHandler = new PollingHandler(new WeakReference<>(mVpBanner));
        if (mCurrentViewList != null){
            setViewList(mCurrentViewList);
        }
        mVpBanner.setPageTransformer(true, new ViewPager.PageTransformer() {
            @Override
            public void transformPage(@NonNull View page, float position) {
                if (position <= 1 && position >=  0){
                    page.setScaleX(1 - position * 0.2f);
                    page.setScaleY(1 - position * 0.2f);
                }else if (position >= -1 && position < 0){
                    page.setScaleX(1 + position * 0.2f);
                    page.setScaleY(1 + position * 0.2f);
                }else {
                    page.setScaleX(0.8f);
                    page.setScaleY(0.8f);
                }
            }
        });
        mVpBanner.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            private int position;
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                this.position = position;
                if (position == 0){
                    mVpBanner.setCurrentItem(mCurrentViewList.size() - 4, false);
                } else if (position == mCurrentViewList.size() - 1) {
                    mVpBanner.setCurrentItem(3, false);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                if (state == ViewPager.SCROLL_STATE_DRAGGING){
                    stopPolling();
                }else if (state == ViewPager.SCROLL_STATE_IDLE){
                    startPolling();
                }
                if (mCurrentViewList == null || mCurrentViewList.size() <= 1){
                    return;
                }
                if (position == 1) {
                    mVpBanner.setCurrentItem(mCurrentViewList.size() - 3, false);
                } else if (position == mCurrentViewList.size() - 2) {
                    mVpBanner.setCurrentItem(2, false);
                } else if (position == 0 && state == ViewPager.SCROLL_STATE_IDLE){
                    mVpBanner.setCurrentItem(mCurrentViewList.size() - 4, false);
                } else if (position == mCurrentViewList.size() - 1 && state == ViewPager.SCROLL_STATE_IDLE) {
                    mVpBanner.setCurrentItem(3, false);
                }
            }
        });
        return view;
    }

    private void setViewList(List<View> list){
        mAdapter.setViewList(list);
        if (list == null){
            return;
        }
        if (list.size() > 1){
            mVpBanner.setCurrentItem(2);
            startPolling();
        }
        if (list.size() < 3){
            mVpBanner.setOffscreenPageLimit(list.size());
        }else {
            mVpBanner.setOffscreenPageLimit(3);
        }
    }

    public void setViewList(List<View> list, Cloneable cloneable){
        List<View> viewList = initViewList(list, cloneable);
        mCurrentViewList = viewList;
        if (mAdapter == null){
            return;
        }
        mAdapter.setViewList(viewList);
        if (list == null){
            return;
        }
        if (list.size() > 1){
            mVpBanner.setCurrentItem(2);
            startPolling();
        }
        if (list.size() < 3){
            mVpBanner.setOffscreenPageLimit(list.size());
        }else {
            mVpBanner.setOffscreenPageLimit(3);
        }
    }

    private void startPolling(){
        if (!isPolling) {
            mHandler.sendEmptyMessageDelayed(1, 2000);
            isPolling = true;
        }
    }

    private void stopPolling(){
        if (isPolling) {
            mHandler.removeCallbacksAndMessages(null);
            isPolling = false;
        }
    }

    private List<View> initViewList(List<View> list, Cloneable cloneable){
        if (list == null || list.size() <= 1){
            return list;
        }
        List<View> newList = new ArrayList<>();
        int size = list.size();
        newList.add(cloneable.clone(list.get(size - 2)));
        newList.add(cloneable.clone(list.get(size - 1)));
        newList.addAll(list);
        newList.add(cloneable.clone(list.get(0)));
        newList.add(cloneable.clone(list.get(1)));
        return newList;
    }

    class ViewpagerAdapter extends PagerAdapter {

        private List<View> list;

        ViewpagerAdapter(){}

        public ViewpagerAdapter(List<View> list){
            this.list = list;
        }

        @Override
        public int getCount() {
            return list == null ? 0 : list.size();
        }

        public void setViewList(List<View> list){
            this.list = list;
            notifyDataSetChanged();
        }

        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
            return view == object;
        }

        @Override
        public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
            container.removeView(list.get(position));
        }

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            container.addView(list.get(position));
            return list.get(position);
        }
    }

    static class PollingHandler extends Handler{

        private ViewPager mViewPager;

        public PollingHandler(WeakReference<ViewPager> reference){
            mViewPager = reference.get();
        }

        @Override
        public void handleMessage(Message msg) {
            mViewPager.setCurrentItem(mViewPager.getCurrentItem() + 1);
            sendEmptyMessageDelayed(1, 2000);
            super.handleMessage(msg);
        }
    }

    public interface Cloneable{
        /**
         * 克隆一个view
         * @param view  原数据
         * @return      目标数据
         */
        View clone(View view);
    }
}
